package com.sugar.follow.up.module.business.service.followuptemplate;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.StyleSet;
import com.sugar.follow.up.module.business.dal.dataobject.followuptemplatequestion.FollowUpTemplateQuestionDO;
import com.sugar.follow.up.module.business.dal.dataobject.questionnairetemplatequestion.dto.OptionDTO;
import com.sugar.follow.up.module.business.dal.mysql.followuptemplatequestion.FollowUpTemplateQuestionMapper;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.net.URLEncoder;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import com.sugar.follow.up.module.business.controller.admin.followuptemplate.vo.*;
import com.sugar.follow.up.module.business.dal.dataobject.followuptemplate.FollowUpTemplateDO;
import com.sugar.follow.up.framework.common.pojo.PageResult;
import com.sugar.follow.up.framework.common.pojo.PageParam;
import com.sugar.follow.up.framework.common.util.object.BeanUtils;

import com.sugar.follow.up.module.business.dal.mysql.followuptemplate.FollowUpTemplateMapper;

import static com.sugar.follow.up.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.sugar.follow.up.framework.common.util.collection.CollectionUtils.convertList;
import static com.sugar.follow.up.framework.common.util.collection.CollectionUtils.diffList;
import static com.sugar.follow.up.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
import static com.sugar.follow.up.module.business.enums.ErrorCodeConstants.*;

/**
 * 随访模板 Service 实现类
 *
 * @author Ysugar
 */
@Service
@Validated
public class FollowUpTemplateServiceImpl implements FollowUpTemplateService {

    @Resource
    private FollowUpTemplateMapper followUpTemplateMapper;
    @Resource
    private FollowUpTemplateQuestionMapper followUpTemplateQuestionMapper;

    @Override
    public Long createFollowUpTemplate(FollowUpTemplateSaveReqVO createReqVO) {
        // 插入
        FollowUpTemplateDO followUpTemplate = BeanUtils.toBean(createReqVO, FollowUpTemplateDO.class);
        followUpTemplateMapper.insert(followUpTemplate);

        // 返回
        return followUpTemplate.getId();
    }

    @Override
    public void updateFollowUpTemplate(FollowUpTemplateSaveReqVO updateReqVO) {
        // 校验存在
        validateFollowUpTemplateExists(updateReqVO.getId());
        // 更新
        FollowUpTemplateDO updateObj = BeanUtils.toBean(updateReqVO, FollowUpTemplateDO.class);
        followUpTemplateMapper.updateById(updateObj);
    }

    @Override
    public void deleteFollowUpTemplate(Long id) {
        // 校验存在
        validateFollowUpTemplateExists(id);
        // 删除
        followUpTemplateMapper.deleteById(id);
    }

    @Override
    public void deleteFollowUpTemplateListByIds(List<Long> ids) {
        // 删除
        followUpTemplateMapper.deleteByIds(ids);
    }


    private void validateFollowUpTemplateExists(Long id) {
        if (followUpTemplateMapper.selectById(id) == null) {
            throw exception(FOLLOW_UP_TEMPLATE_NOT_EXISTS);
        }
    }

    @Override
    public FollowUpTemplateDO getFollowUpTemplate(Long id) {
        return followUpTemplateMapper.selectById(id);
    }

    @Override
    public PageResult<FollowUpTemplateDO> getFollowUpTemplatePage(FollowUpTemplatePageReqVO pageReqVO) {
        return followUpTemplateMapper.selectPage(pageReqVO);
    }

    @Override
    public void exportFollowUpTemplateExcel(FollowUpTemplatePageReqVO pageReqVO, HttpServletResponse response) throws IOException {
        // 自定义头部标题
        List<String> headList1 = CollUtil.newArrayList("序号", "模板名称", "需要填写姓名", "需要选择年龄", "需要选择性别", "需要选择日期", "选项信息", "", "", "", "");
        List<String> headList2 = CollUtil.newArrayList("", "", "", "", "", "", "题目", "题型", "提示语", "选项标题", "选项内容");

        ExcelWriter writer = ExcelUtil.getWriter(/*"E:/test/writeBeanTest.xlsx"*/);

        // 获取样式
        StyleSet style = writer.getStyleSet();
        Font headFont = writer.createFont();
        headFont.setBold(true);
        headFont.setFontHeightInPoints((short) 16);
        //重点，设置中文字体
        headFont.setFontName("楷体");
        style.setWrapText();
        // 设置头部标题字体与背景色
        style.getHeadCellStyle().setFont(headFont);
        style.getHeadCellStyle().setFillForegroundColor(IndexedColors.WHITE.getIndex());

        // 写入头部标题
        writer.writeHeadRow(headList1);
        writer.writeHeadRow(headList2);

        // 获取所有模板
        List<FollowUpTemplateDO> templates = followUpTemplateMapper.selectPage(pageReqVO).getList();
        int templateRowNum = 2;
        int rowNum = 2;
        int idx = 1;
        for (FollowUpTemplateDO template : templates) {
            String title = template.getTitle();
            String needInputName = getBoolStr(template.getNeedInputName());
            String needSelAge = getBoolStr(template.getNeedSelAge());
            String needSelGender = getBoolStr(template.getNeedSelGender());
            String needSelDate = getBoolStr(template.getNeedSelDate());

            // 根据模板获取题目
            List<FollowUpTemplateQuestionDO> questions = followUpTemplateQuestionMapper.selectList(FollowUpTemplateQuestionDO::getTemplateId, template.getId());
            int size = questions.size();
            if (size == 0) {
                // 构建该行每个单元格内容
                ArrayList<String> rowPlanContents = CollUtil.newArrayList("" + idx, title,
                        needInputName, needSelAge, needSelGender, needSelDate, "", "", "", "", "");
                writer.writeRow(rowPlanContents);
                rowNum += 1;
                templateRowNum += 1;
            } else {
                for (int i = 0; i < size; i++) {
                    FollowUpTemplateQuestionDO question = questions.get(i);

                    // 获取题型
                    String questionType = getQuestionType(question.getType());

                    List<OptionDTO> options = question.getOptions();
                    int optionSize = Objects.nonNull(options) ? options.size() : 0;
                    if (optionSize == 0) {
                        // 构建该行每个单元格内容
                        ArrayList<String> rowPlanContents = CollUtil.newArrayList("" + idx, title,
                                needInputName, needSelAge, needSelGender, needSelDate, question.getTitle(), questionType, question.getTip(), "", "");
                        writer.writeRow(rowPlanContents);
                        optionSize = 1;
                    } else {
                        for (OptionDTO option : options) {
                            // 构建该行每个单元格内容
                            ArrayList<String> rowPlanContents = CollUtil.newArrayList("" + idx, title,
                                    needInputName, needSelAge, needSelGender, needSelDate, question.getTitle(), questionType, question.getTip(), option.getTitle(), option.getContent());
                            writer.writeRow(rowPlanContents);
                        }
                    }

                    int lastRow = rowNum + optionSize - 1;

                    if (lastRow > rowNum){
                        writer.merge(rowNum, lastRow, 6, 6, question.getTitle(), false);
                        writer.merge(rowNum, lastRow, 7, 7, questionType, false);
                        writer.merge(rowNum, lastRow, 8, 8, question.getTip(), false);
                    }
                    rowNum += optionSize;
                }

                int lastRow = rowNum;

                if (rowNum > templateRowNum)
                    lastRow -= 1;

                if (lastRow > templateRowNum){
                    writer.merge(templateRowNum, lastRow, 0, 0, idx, false);
                    writer.merge(templateRowNum, lastRow, 1, 1, title, false);
                    writer.merge(templateRowNum, lastRow, 2, 2, needInputName, false);
                    writer.merge(templateRowNum, lastRow, 3, 3, needSelAge, false);
                    writer.merge(templateRowNum, lastRow, 4, 4, needSelGender, false);
                    writer.merge(templateRowNum, lastRow, 5, 5, needSelDate, false);
                }
                templateRowNum = rowNum;
            }

            idx++;
        }

        // 合并标题单元格
        writer.merge(0, 1, 0, 0, "序号", true);
        writer.merge(0, 1, 1, 1, "模板名称", true);
        writer.merge(0, 1, 2, 2, "需要填写姓名", true);
        writer.merge(0, 1, 3, 3, "需要选择年龄", true);
        writer.merge(0, 1, 4, 4, "需要选择性别", true);
        writer.merge(0, 1, 5, 5, "需要选择日期", true);
        writer.merge(0, 0, 6, 10, "选项信息", true);

        writer.setOnlyAlias(true);
        writer.autoSizeColumnAll();

        writer.setColumnWidth(0, 10);
        writer.setColumnWidth(1, 20);
        writer.setColumnWidth(2, 20);
        writer.setColumnWidth(3, 20);
        writer.setColumnWidth(4, 20);
        writer.setColumnWidth(5, 20);
        writer.setColumnWidth(6, 25);
        writer.setColumnWidth(7, 10);
        writer.setColumnWidth(8, 15);
        writer.setColumnWidth(9, 13);
        writer.setColumnWidth(10, 25);

        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        // test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("随访模板信息.xls", "UTF-8"));
        ServletOutputStream out = response.getOutputStream();

        writer.flush(out, true);
        // 关闭writer，释放内存
        writer.close();
        // 此处记得关闭输出Servlet流
        IoUtil.close(out);
    }

    @Override
    public List<FollowUpTemplateSimpleRespVO> getFollowUpTemplateAll() {
        return BeanUtils.toBean(followUpTemplateMapper.selectList(), FollowUpTemplateSimpleRespVO.class);
    }

    private String getBoolStr(Boolean flag) {
        return Objects.nonNull(flag) && flag ? "是" : "否";
    }

    private String getQuestionType(Integer type) {
        switch (type){
            case 0:
                return "单选题";
            case 1:
                return "多选题";
            case 2:
                return "填空题";
            case 3:
                return "问答题";
            case 4:
                return "日期选择";
            default:
                return "-";
        }
    }

}